package com.fishy.chat.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.fishy.chat.action.ChannelAction;
import com.fishy.chat.enums.MessageType;
import com.fishy.chat.model.dto.LoginDTO;
import com.fishy.chat.model.entity.Message;
import com.fishy.common.result.ResultCode;
import com.fishy.system.model.entity.User;
import com.fishy.system.service.UserService;
import io.netty.channel.ChannelHandlerContext;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 请求消息处理器
 *
 * @author sunn
 */
@Slf4j
@Component
public class RequestMessageHandler {

    @Resource
    private UserService userService;

    /**
     * 入口方法-请求派发
     */
    public void handle(ChannelHandlerContext ctx, Message message) {
        MessageType type = message.getType();
        switch (type) {
            case USER -> handleUserMessage(ctx, message);
            case LOGIN -> handleLoginMessage(ctx, message);
            default -> handleUnknownMessage(ctx, message);
        }
    }

    /**
     * 处理登录消息
     */
    private void handleLoginMessage(ChannelHandlerContext ctx, Message message) {
        // 检查是否已经登陆
        if (ChannelAction.checkLogin(ctx.channel().id())) {
            ctx.channel().writeAndFlush(new Message(MessageType.ERROR, "请勿重复登录！"));
            return;
        }
        String loginBody = message.getBody();
        LoginDTO loginDTO;
        // 反序列化登录消息
        try {
            loginDTO = JSONUtil.toBean(loginBody, LoginDTO.class);
        } catch (Exception e) {
            System.err.println("反序列化登陆消息失败: " + loginBody);
            ctx.close();
            return;
        }
        // 处理登录逻辑
        String userId = loginDTO.getUserId();
        User user = userService.getById(Long.valueOf(userId));
        if (BeanUtil.isEmpty(user)) {
            Message response = new Message(MessageType.ERROR, ResultCode.USER_LOGIN_EXCEPTION.getMsg());
            ctx.channel().writeAndFlush(response);
            ctx.close();
        }
        // 登录成功，发送上线消息
        ChannelAction.add(ctx.channel());
        Message onlineMessage = new Message(MessageType.USER_ONLINE, user.getNickname());
        ChannelAction.send(onlineMessage);
        log.info("用户登录成功: {}", user.getNickname());
    }

    /**
     * 处理用户消息
     */
    private void handleUserMessage(ChannelHandlerContext ctx, Message message) {
        if (!ChannelAction.checkLogin(ctx.channel().id())) {
            Message response = new Message(MessageType.ERROR, "请先登录！");
            ctx.channel().writeAndFlush(response);
            return;
        }
        log.info("广播用户消息: {}", message);
        // 广播用户消息给所有在线用户
        ChannelAction.send(message);
    }

    /**
     * 处理未知消息
     */
    private void handleUnknownMessage(ChannelHandlerContext ctx, Message message) {
        log.error("接收到未知类型消息，关闭连接: {}", message);
        Message response = new Message(MessageType.ERROR, "因为您发送了不支持的消息类型，连接已关闭");
        ctx.channel().writeAndFlush(response);
        ctx.close();
    }
}
